//
//  FetchedResultsUITableViewController.m
//  Sudoku
//
//  Created by Richard Hodgkins on 29/09/2012.
//  Copyright (c) 2012 Richard Hodgkins. All rights reserved.
//

#import "FetchedResultsUITableViewController.h"

@implementation FetchedResultsUITableViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {       
        // Setup delegates
        self.tableView.delegate = self;
    }
    return self;
}

-(void)setDelegate:(id<FetchedResultsDataSourceDelegate>)delegate
{
    if (_delegate != delegate) {
        _delegate = delegate;
        [_delegate resultsController].delegate = self;
        [self performFetch];
    }
}

-(NSError *) performFetch
{
    NSError *error = nil;
    const BOOL wasFetched = [[self.delegate resultsController] performFetch:&error];
    if (!wasFetched) {
        NSLog(@"Problem fetching results: %@", error);
    }
    return error;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [[[self.delegate resultsController] sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in a section.
    return [[[[self.delegate resultsController] sections] objectAtIndex:section] numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self.delegate tableView:self.tableView newCellForRowAtIndexPath:indexPath];
    [self.delegate tableView:self.tableView updateCellForRow:cell atIndexPath:indexPath];
    return cell;
}

#pragma mark - Fetch results delegate

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
    
    UITableViewRowAnimation animation = [self tableViewRowAnimationForChangeType:type];
    UITableView *tableView = self.tableView;
    
    switch (type) {
            
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:animation];
            break;
            
        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:animation];
            break;
            
        case NSFetchedResultsChangeUpdate:
            {
                UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
                [self.delegate tableView:tableView updateCellForRow:cell atIndexPath:indexPath];
            }
            break;
            
        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:animation];
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:animation];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    
    UITableViewRowAnimation animation = [self tableViewRowAnimationForChangeType:type];
    UITableView *tableView = self.tableView;
    
    switch(type) {
            
        case NSFetchedResultsChangeInsert:
            [tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:animation];
            break;
            
        case NSFetchedResultsChangeDelete:
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:animation];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];
}

- (UITableViewRowAnimation)tableViewRowAnimationForChangeType:(NSFetchedResultsChangeType) type
{
    return UITableViewRowAnimationFade;
}

@end
